﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Windows.Forms;
using System.ComponentModel;
using System.Reflection;
using System.Threading;

namespace Loki.UI.Win
{
	public class NotifyPropertyChangedWrapper<T> : INotifyPropertyChanged
	{
		private static Dictionary<string, PropertyChangedEventArgs> _EventArgs = new Dictionary<string, PropertyChangedEventArgs>();
		private static object _lock = new object();

		private string _PropertyName;
		public NotifyPropertyChangedWrapper(Expression<Func<T, object>> P_Property)
		{
			_PropertyName = ExpressionHelper.Reflect<T>.GetProperty(P_Property).Name;
			lock (_lock)
			{
				if (!_EventArgs.ContainsKey(_PropertyName))
				{
					_EventArgs[_PropertyName] = ObservableHelper.CreateArgs(P_Property);
				}
			}
		}

		#region Event
		private readonly object PropertyChangedEventLock = new object();
		private PropertyChangedEventHandler PropertyChangedEvent;

		/// <summary>
		/// Event raised after the <see cref="Text" /> property value has changed.
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged
		{
			add
			{
				lock (PropertyChangedEventLock)
				{
					PropertyChangedEvent += value;
				}
			}
			remove
			{
				lock (PropertyChangedEventLock)
				{
					PropertyChangedEvent -= value;
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="PropertyChanged" /> event.
		/// </summary>
		/// <param name="e"><see cref="PropertyChangedEventArgs" /> object that provides the arguments for the event.</param>
		protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			PropertyChangedEventHandler handler = null;

			lock (PropertyChangedEventLock)
			{
				handler = PropertyChangedEvent;

				if (handler == null)
					return;
			}

			handler(this, e);
		}
		#endregion

		public void EventBridge(object sender, EventArgs e)
		{
			OnPropertyChanged(_EventArgs[_PropertyName]);
		}
	}
}
